home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
lang
/
mc302
/
cutil
/
obscure.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-18
|
8KB
|
281 lines
/*
* Program to obscure the meaning of a MICRO-C source file by
* removing comments, indenting, and line spacing. All non-reserved
* words are replaced with meaningless numeric names.
*
* Syntax: obscure <input_file> [output_file] [options]
*
* Options: k=<filename> - File of names to KEEP (1 per line).
* d=<filename> - File of names to PRE-DEFINE (1 per line).
* p=<string> - Prefix pre-pended to generated numeric names.
*
* Use 'k=' to prevent certain names from being obscured.
* Use 'd=' to insure that certain names will have the same obscured
* name in several modules (For "extern"s etc.).
* Default 'p=' prefix is '_'.
*
* For MAXIMUM obscuring, use the pre-processor (MCP) before processing
* with this program. This will remove all pre-processor directives, but BE
* WARNED that this will make the program LESS PORTABLE, since key system
* header files (Such as <stdio.h>) will not be re-used when moving to a
* a new system.
*
* Copyright 1989-1994 Dave Dunfield
* All rights reserved.
*
* Permission granted for personal (non-commercial) use only.
*
* Compile command: cc obscure -fop
*/
#include <stdio.h>
#define NUMNEW 500 /* maximum number of unique words */
#define NUMKEEP 100 /* maximum number of kept words */
#define FREEPOOL 15000 /* size of free storage pool */
#define MAXWIDTH 70 /* maximum width of output line */
/* table of reserved words to keep without changing */
char *resword[] = {
/* MICRO-C keywords */
"break", "case", "char", "continue", "default", "do", "else",
"extern", "for", "goto", "if", "int", "register", "return", "static",
"switch", "unsigned", "while", "include", "define", "endif" ,"ifdef",
"ifndef", "undef", "forget", "struct", "union", "sizeof",
/* MICRO-C library functions */
"abort", "fprintf", "islower", "peekw", "strchr", "abs", "fwrite",
"isspace", "poke", "strcmp", "atoi", "fputs", "isupper", "pokew",
"strcpy", "cd", "free", "longjmp", "printf", "strlen", "concat",
"fscanf", "malloc", "putc", "strncat", "create", "fseek", "max",
"rename", "strncmp", "delete", "ftell", "memcpy", "rewind", "strncpy",
"exit", "getc", "memset", "rmdir", "strstr", "fclose", "getenv", "min",
"scanf", "system", "fread", "getdir", "mkdir", "setjmp", "toupper",
"fgets", "in", "nargs", "sprintf", "tolower", "find_first", "inw",
"out", "sscanf", "find_next", "isalpha", "outw", "strbeg", "fopen",
"isdigit", "peek", "strcat", "alloc_seg", "vdraw_box", "get_es", "tsr",
"Cclose", "vtstc", "enable", "get_time", "updatexy", "Cgetc", "rand",
"vclear_box", "exec", "gotoxy", "version", "Copen", "clear_eol",
"free_seg", "vgets", "Cputc", "clear_eos", "Ctestc", "resize_seg",
"Csignals", "clscr", "get_attr", "set_attr", "isalnum", "fflush",
"vopen", "vgetc", "vputc", "vmenu", "copy_seg", "get_cs", "vmessage",
"cursor_off", "cursor_line", "cursor_block", "get_date", "set_date",
"set_drive", "vprintf", "get_drive", "set_es", "vputf", "disable",
"get_ds", "set_time", "vputs", "save_video", "restore_video", "main",
"open", "close", "read", "write", "lrewind", "lseek", "ltell", "lprintf",
"lgetc", "lputc", "lgets", "lputs", "setbuf", "cpu", "int86",
/* Common header file definitions */
"FILE", "EOF", "NULL", "stdin", "stdout", "stderr", "mc", "h", "comm",
"console", "ctype", "file", "stdio", "tsr", "window", "video",
0 };
unsigned new_count = 0, keep_count = 0, width = 0;
int inpos = -1;
char *new_text[NUMNEW], *keep_text[NUMKEEP], buffer[200],
free_text[FREEPOOL], *free_ptr, *prefix = "_", pflag = 0;
FILE *fpr = 0, *fpw;
/*
* Main program
*/
main(argc, argv)
int argc;
char *argv[];
{
int chr, chr1, i;
char *ptr;
FILE *fp;
free_ptr = free_text;
fpw = stdout;
for(i=1; i < argc; ++i) {
ptr = argv[i];
switch((*ptr++ << 8) | *ptr++) {
case 'p=' : /* define generation prefix */
prefix = ptr;
break;
case 'd=' : /* define symbols in advance */
fp = fopen(ptr, "rvq");
while(fgets(buffer, 100, fp)) {
new_text[new_count++] = free_ptr;
ptr = buffer;
do
*free_ptr++ = *ptr;
while(*ptr++); }
fclose(fp);
break;
case 'k=' : /* define names to keep */
fp = fopen(ptr, "rvq");
while(fgets(buffer, 100, fp)) {
keep_text[keep_count++] = free_ptr;
ptr = buffer;
do
*free_ptr++ = *ptr;
while(*ptr++); }
fclose(fp);
break;
default: /* filename */
if(!fpr)
fpr = fopen(argv[i], "rvq");
else if(fpw == stdout)
fpw = fopen(argv[i], "wvq");
else
abort("Too many operands\n"); } }
/* if no input file specified, report error */
if(!fpr) {
fputs("\nUse: obscure <input_file> [output_file d=definefile k=keepfile p=prefix]\n", stderr);
abort("\nCopyright 1989-1994 Dave Dunfield\nAll rights reserved.\n"); }
keep_text[keep_count] = new_text[new_count] = 0;
while((chr = read_char()) >= 0) {
top: switch(chr) {
case '\n' : /* newline */
if(pflag) {
putc('\n', fpw);
pflag = width = 0; }
case '\t' : /* ignore tab */
case ' ' : /* ignore space */
break;
case '/' : /* starting comment */
if((chr = read_char()) == '*') {
do
if((chr1 = read_char()) < 0)
abort("End of file in comment\n");
while((chr = (chr << 8) + chr1) != '*/'); }
else {
write_char('/');
goto top; }
break;
case '"' : /* string input */
case '\'': /* character input */
buffer[i=0] = chr;
do {
buffer[++i] = chr1 = read_char();
if(chr1 == '\\')
buffer[++i] = read_char(); }
while(chr1 != chr);
buffer[++i] = 0;
check_width(width+i);
write_string(buffer);
break;
case '#' : /* pre-processor statements */
if(!inpos) {
pflag = -1;
if(width) {
putc('\n', fpw);
width = 0; } }
default: /* all other characters */
if(isvar(chr)) { /* Variable name */
check_width(width);
buffer[i = 0] = chr;
do
buffer[++i] = chr = read_char();
while(isvar(chr) || isdigit(chr));
buffer[i] = 0;
if((!lookup(resword)) && !lookup(keep_text)) {
if(!(chr1 = lookup(new_text))) {
new_text[new_count++] = free_ptr;
ptr = buffer;
do
*free_ptr++ = *ptr;
while(*ptr++);
new_text[chr1 = new_count] = 0; }
sprintf(buffer, "%s%u", prefix, chr1); }
write_string(buffer);
while(isspace(chr)) {
if(pflag && (chr == '\n'))
break;
chr = read_char(); }
if(isvar(chr) || isdigit(chr))
write_char(' ');
goto top; }
else if(isdigit(chr)) { /* number */
check_width(width);
do
write_char(chr);
while(isdigit(chr = read_char()));
if(chr == 'x') {
do {
write_char(chr);
chr = read_char(); }
while(isxdigit(chr)); }
goto top; }
else
write_char(chr); } }
fclose(fpw);
}
/*
* Lookup the buffered word in a table
*/
lookup(table)
char *table[];
{
int i;
char *ptr;
i = 0;
while(ptr = table[i++])
if(!strcmp(buffer, ptr))
return i;
return 0;
}
/*
* Test for valid variable character
*/
isvar(chr)
char chr;
{
return ((chr >= 'a') && (chr <= 'z')) ||
((chr >= 'A') && (chr <= 'Z')) ||
(chr == '_');
}
/*
* Read a character from the input file
*/
read_char()
{
char chr;
inpos = ((chr = getc(fpr)) == '\n') ? -1 : inpos + 1;
return chr;
}
/*
* Write a character to the file
*/
write_char(chr)
char chr;
{
putc(chr, fpw);
++width;
}
/*
* Write a string to the file
*/
write_string(string)
char *string;
{
while(*string) {
putc(*string++, fpw);
++width; }
}
/*
* Check for over width in output file
*/
check_width(value)
unsigned value;
{
if(value >= MAXWIDTH) {
putc('\n', fpw);
width = 0; }
}